/*
 * @ProblemId: 
 * @Probtitle: 
 * @Location: 
 * @Author: Morales
 * @Date: 2020-10-16 08:00:16
 * @LastEditTime: 2020-10-16 08:40:24
 * @Space: https://space.bilibili.com/350869102
 * @E-mail: lovexposed@foxmail.com
 * @Blog: https://blog.csdn.net/baidu_41248654
 * @Powered by: Havoc_Wei
 */
//使用队列输出杨辉三角
//#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define maxsize 50
using namespace std;
typedef struct{
    int elem[maxsize];
    int head, tail;
}Sq;

void InitQ(Sq &q)
{
    q.head = 0;
    q.tail = 0;
}
bool IsEmpty(Sq q)
{
    if(q.head == q.tail) return 1;
    else return 0;
}
bool EnQ(Sq &q, int data)
{
    if((q.tail+1)%maxsize == q.head) return 0;
    q.elem[q.tail] = data;
    q.tail = (q.tail+1)%maxsize;
    return 1;
}
bool DeQ(Sq &q, int &data)
{
    if(IsEmpty(q)) return 0;
    data = q.elem[q.head];
    q.head = (q.head+1)%maxsize;
    return 1;
}
int GetHead(Sq q)
{
    if(!IsEmpty(q))
        return q.elem[q.head];
}

void YHTriangle(int n)
{
    Sq q;
    InitQ(q);
    EnQ(q, 1);
    int top = n;
    for(int i=2; i<=n; i++)
    {
        //cout<<"<"<<endl;
        for(int k=1; k<=top; k++)
            printf(" ");
        top--;
        EnQ(q, 1);
        int tmp;
        for(int j=1; j<=i-2; j++)
        {
            DeQ(q, tmp);
            //cout<<tmp<<" ";
            printf("%2d ", tmp);
            tmp += GetHead(q);
            EnQ(q, tmp);
        }
        DeQ(q, tmp);
        //cout<<tmp<<" ";
        printf("%2d ", tmp);
        EnQ(q, 1);
        cout<<endl;
    }
    while(!IsEmpty(q))
    {
        int tmp;
        DeQ(q, tmp);
        //cout<<tmp<<"  ";
        printf("%2d ", tmp);
    }
}
int main()
{
    //ios::sync_with_stdio(false);
    int n;
    cin>>n;
    YHTriangle(n);
    cout<<endl;
    return 0;
}